/*
 * Copyright (c) 2024 IPC Project
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 */

#ifndef ONVIF_SOAP_MESSAGE_HPP
#define ONVIF_SOAP_MESSAGE_HPP

#include <string>
#include <map>
#include <memory>
#include <vector>
#include <mutex>
#include "onvif_types.h"

namespace El {
namespace Onvif {

/**
 * @brief SOAP错误类型枚举
 */
enum class SoapError {
    NONE = 0,
    InvalidMessage,
    InvalidAction,
    AuthenticationFailed,
    AuthorizationFailed,
    InternalError,
    NotSupported,
    BadRequest
};

/**
 * @brief SOAP请求处理接口
 */
class ISoapHandler {
public:
    virtual ~ISoapHandler() = default;
    virtual std::string HandleRequest(const SoapMessage& request, const std::string& remoteAddr) = 0;
};

/**
 * @brief SOAP消息解析器类
 * 负责解析SOAP请求和生成SOAP响应
 */
class SoapMessageParser {
public:
    SoapMessageParser();
    ~SoapMessageParser();

    /**
     * @brief 解析SOAP请求消息
     * @param soapXml SOAP消息内容
     * @return 解析后的SoapMessage结构
     */
    SoapMessage ParseSoapRequest(const std::string& soapXml) const;

    /**
     * @brief 生成SOAP响应消息
     * @param responseBody 响应体内容
     * @param action SOAP Action
     * @return SOAP响应消息字符串
     */
    std::string GenerateSoapResponse(const std::string& responseBody, const std::string& action) const;

    /**
     * @brief 生成SOAP错误响应
     * @param error 错误类型
     * @param detail 错误详细信息
     * @return SOAP错误响应消息字符串
     */
    std::string GenerateSoapFault(SoapError error, const std::string& detail = "") const;

    /**
     * @brief 验证WS-Security令牌
     * @param message SOAP消息
     * @param expectedUser 期望的用户名
     * @param expectedPass 期望的密码
     * @return 验证是否成功
     */
    bool ValidateWSSecurity(const SoapMessage& message, const std::string& expectedUser, const std::string& expectedPass) const;

private:
    /**
     * @brief 解析SOAP头部
     * @param soapXml SOAP消息
     * @return Header内容
     */
    std::string ParseSoapHeader(const std::string& soapXml) const;

    /**
     * @brief 解析SOAP Body
     * @param soapXml SOAP消息
     * @return Body内容
     */
    std::string ParseSoapBody(const std::string& soapXml) const;

    /**
     * @brief 提取SOAP Action
     * @param soapXml SOAP消息
     * @return Action字符串
     */
    std::string ExtractSoapAction(const std::string& soapXml) const;

    /**
     * @brief 检查WS-Security
     * @param soapXml SOAP消息
     * @return 是否包含WS-Security
     */
    bool CheckWSSecurity(const std::string& soapXml) const;

    /**
     * @brief 提取凭据
     * @param soapXml SOAP消息
     * @return 用户名和密码的pair
     */
    std::pair<std::string, std::string> ExtractCredentials(const std::string& soapXml) const;

    /**
     * @brief 转义XML特殊字符
     * @param input 原始文本
     * @return 转义后的文本
     */
    std::string EscapeXml(const std::string& input) const;

    /**
     * @brief 生成时间戳
     * @return 当前时间戳字符串
     */
    std::string GenerateTimestamp() const;

private:
    bool securityEnabled_;
    std::map<std::string, std::string> defaultNamespaces_;
};

/**
 * @brief SOAP服务分发器
 * 负责将SOAP请求分发到对应的服务处理器
 */
class SoapDispatcher {
public:
    SoapDispatcher();
    ~SoapDispatcher();

    /**
     * @brief 注册服务处理器
     * @param action 动作名称
     * @param handler 处理器实例
     */
    void RegisterHandler(const std::string& action, std::shared_ptr<ISoapHandler> handler);

    /**
     * @brief 注销服务处理器
     * @param action 动作名称
     */
    void UnregisterHandler(const std::string& action);

    /**
     * @brief 处理SOAP请求
     * @param soapXml SOAP XML内容
     * @param remoteAddr 远程地址
     * @return 响应内容
     */
    std::string ProcessRequest(const std::string& soapXml, const std::string& remoteAddr) const;

    /**
     * @brief 处理HTTP SOAP请求
     * @param method HTTP方法
     * @param path 请求路径
     * @param headers HTTP头部
     * @param body 请求体
     * @param remoteAddr 远程地址
     * @return 响应内容
     */
    std::string ProcessHttpRequest(const std::string& method,
                                  const std::string& path,
                                  const std::string& headers,
                                  const std::string& body,
                                  const std::string& remoteAddr) const;

    /**
     * @brief 设置认证模式
     * @param mode 安全模式
     */
    void SetAuthenticationMode(SecurityMode mode);

    /**
     * @brief 设置认证凭据
     * @param username 用户名
     * @param password 密码
     */
    void SetCredentials(const std::string& username, const std::string& password);

    /**
     * @brief 验证认证
     * @param message SOAP消息
     * @return 是否通过认证
     */
    bool ValidateAuthentication(const SoapMessage& message) const;

private:
    /**
     * @brief 生成HTTP错误响应
     * @param statusCode 状态码
     * @param statusText 状态文本
     * @return HTTP错误响应
     */
    std::string GenerateHttpError(int statusCode, const std::string& statusText) const;

private:
    mutable std::mutex handlersMutex_;
    mutable std::mutex authMutex_;
    std::map<std::string, std::shared_ptr<ISoapHandler>> handlers_;
    SecurityMode authMode_;
    std::string username_;
    std::string password_;
};

} // namespace Onvif
} // namespace El

#endif // ONVIF_SOAP_MESSAGE_HPP 